import Buffer from 'buffer';
import aesjs from 'aes-js';
import { aesConfig, aliCloud, aliUrl } from './env';
import { Loading } from 'element-ui';
import axios from 'axios';


/**
 * aes加密上传
 * 使用方法 await fileUploadAes(file,'/path/path/')
 * @param {*} file  input的file
 * @param {*} path  存放的路径
 */
const fileUploadAes = async (file, path) => {
    return new Promise(async reslove => {
        // let loadingInstance = await Loading.service({ fullscreen: true });
        const chars = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'];
        let res = "";
        for(let i = 0; i < 15; i++) {
            let id = Math.ceil(Math.random() * 61);
            res += chars[id];
        }
        // console.log(res, "res")

        const key = res + '.' + file.name.split(/\./g).pop(); // 保存到bos时的key，您可更改，默认以文件名作为key
        // console.log(key, blob, "change")
        const data = await mediaFileReader(file);
        console.log(data,'...data')
        const fileBuffer = Buffer.Buffer(data);
        console.log(fileBuffer,'...data')
        const aesCbc = new aesjs.ModeOfOperation.cbc(aesConfig.key, aesConfig.iv);
        const encryptedBytes = aesCbc.encrypt(aesjs.padding.pkcs7.pad(fileBuffer));
        let options = {
            'Content-Length': 0, // 添加http header
            'Content-Type': 'application/octet-stream;charset=utf-8', // 添加http header
            'Content-Encoding': 'binary'
        };
        // buffer形式上传
        options['Content-Length'] = encryptedBytes.byteLength;
        // '/edu/'
        // console.log('/'+path +'/'+key+'x', '....')
        aliCloud.put('/'+path +'/'+key+'x', Buffer.Buffer(encryptedBytes), {
            progress: (p, cpt, res) => {
                console.log(p);
                // self.imgPercentage =(( p * 100 ).toFixed(0));
                // console.log(self.imgPercentage, "上传图片")

                // // 满了，清空进度条
                // if(self.imgPercentage == 100) {
                //     self.imgPercentage = 0
                //     // document.getElementById('fileArray').value = ''
                // }
            }
        }).then(function(result) {
            // const uploadPath = "https://" + aesConfig.bucket + ".oss-cn-hangzhou.aliyuncs.com" + result.name;
            const uploadPath =  aliUrl + result.name;
            // loadingInstance.close();
            reslove({
                status: 200,
                data: uploadPath
            })
        }).catch( err => {
            console.error(err,'err')
            // loadingInstance.close();
            reslove({
                status: 500,
                msg: '上传失败'
            })
        })
    })
}
// 多媒体文件加载
const mediaFileReader = (file) => {
    return new Promise(resolve => {
        const reader = new FileReader(); //新建一个FileReader
        //          console.log(JSON.stringify(files[0]) )
        // ReadTxt(files[0].value)
        //     reader.readAsText(files[0], "UTF-8");//读取文件
        reader.onload = function(evt) { //读取完文件之后会回来这里
            const fileString = evt.target.result; // 读取文件内容
            // cb(fileString)
            resolve(fileString)
        }
        reader.readAsArrayBuffer(file);
    })
}


/**
 * aes文件解密
 * 使用方法 await fileAesDecode(src)
 * @param {*} src  完整url
 */
const fileAesDecode = (src) => {
    return new Promise( resolve => {
        axios({
            method: 'get',
            // 测试地址 http://mb-bucket.cdn.bcebos.com/NF4s2V.m4a http://mb-bucket.cdn.bcebos.com/vLmR7ErCuWRj.mp3x http://mb-bucket.gz.bcebos.com/mYU7iglfckMc.m4ax
            url: src,
            headers: {
                'Content-Type': 'application/octet-stream;charset=utf-8'
            },
            responseType: 'arraybuffer' // 接收二进制
        })
        .then( async response => {
            // 解密后得到base64
            const b64 = await decrypted(response.data);
            resolve({
                status: 200,
                data: b64
            })
        })
        .catch(err => {
            console.error(err);
            resolve({
                status: 500,
                msg:'解密失败'
            })
        })
    })
}

// 解密音频文件
const decrypted = data => {
    const aesCbc = new aesjs.ModeOfOperation.cbc(aesConfig.key, aesConfig.iv); // 解密的配置
    const decryptedBytes = aesCbc.decrypt(aesjs.padding.pkcs7.pad(Buffer.Buffer(data))); // 得到外链的二进制后，进行解密
    // 解密后的buffer 二进制转base
    return _arrayBufferToBase64(Buffer.Buffer(decryptedBytes))
}
// 二进制转base64
const _arrayBufferToBase64 = async (raw) => {
    let base64 = '';
    let encodings = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
    let bytes = new Uint8Array(raw);
    let byteLength = bytes.byteLength;
    let byteRemainder = byteLength % 3;
    let mainLength = byteLength - byteRemainder;
    let a, b, c, d;
    let chunk;
    // Main loop deals with bytes in chunks of 3
    for(let i = 0; i < mainLength; i = i + 3) {
        // Combine the three bytes into a single integer
        chunk = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2];
        // Use bitmasks to extract 6-bit segments from the triplet
        a = (chunk & 16515072) >> 18; // 16515072 = (2^6 - 1) << 18
        b = (chunk & 258048) >> 12; // 258048 = (2^6 - 1) << 12
        c = (chunk & 4032) >> 6; // 4032 = (2^6 - 1) << 6
        d = chunk & 63; // 63 = 2^6 - 1
        // Convert the raw binary segments to the appropriate ASCII encoding
        base64 += encodings[a] + encodings[b] + encodings[c] + encodings[d];
    }
    // Deal with the remaining bytes and padding
    if(byteRemainder == 1) {
        chunk = bytes[mainLength];
        a = (chunk & 252) >> 2 // 252 = (2^6 - 1) << 2;
        // Set the 4 least significant bits to zero
        b = (chunk & 3) << 4 // 3 = 2^2 - 1;
        base64 += encodings[a] + encodings[b] + '==';
    } else if(byteRemainder == 2) {
        chunk = (bytes[mainLength] << 8) | bytes[mainLength + 1];
        a = (chunk & 16128) >> 8 // 16128 = (2^6 - 1) << 8;
        b = (chunk & 1008) >> 4 // 1008 = (2^6 - 1) << 4;
        // Set the 2 least significant bits to zero
        c = (chunk & 15) << 2 // 15 = 2^4 - 1;
        base64 += encodings[a] + encodings[b] + encodings[c] + '=';
    }
    return "data:audio/mp3;base64," + base64;
}


export {
    fileUploadAes,
    fileAesDecode
}
